using Infrastructure.Attribute;
using Infrastructure.Extensions;
using JTZY.Model.Stock.Dto;
using JTZY.Model.Stock;
using JTZY.Repository;
using JTZY.Service.Stock.IStockService;
using Infrastructure.Enums;
using Infrastructure;
using SqlSugar;
using JinianNet.JNTemplate;
using JTZY.Model.Product;
using JTZY.Model.Goods;
using JTZY.Common;
using static JTZY.Common.GlobalEnumVars;
using JTZY.Model.Business;
using System.Linq;
using System.Collections.Generic;
using YKPrintService.VO;
using Microsoft.Extensions.Logging;
using Aliyun.OSS;
using NLog;
using System;

namespace JTZY.Service.Stock
{
    /// <summary>
    /// 调仓单Service业务层处理
    /// </summary>
    [AppService(ServiceType = typeof(ITransferorderService), ServiceLifetime = LifeTime.Transient)]
    public class TransferorderService : BaseService<Transferorder>, ITransferorderService
    {
        private NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();

        /// <summary>
        /// 查询调仓单列表
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        public PagedInfo<TransferorderDto> GetList(TransferorderQueryDto parm)
        {
            var predicate = QueryExp(parm);

            var response = Queryable()
                .LeftJoin<Corecmsuser>((it, custer) => it.NewUserld == custer.Id)
                //.Includes(x => x.TransferorderitemNav) //填充子对象
                .Where(predicate.ToExpression())
                .WhereIF((parm.cusUserId.HasValue), it => it.NewUserld == parm.cusUserId || it.OldUserId == parm.cusUserId)
                .WhereIF(!string.IsNullOrEmpty(parm.orderId) && parm.orderId.All(char.IsDigit) && parm.orderId.Length == 16, it => it.OrderId == parm.orderId)
                .WhereIF(!string.IsNullOrEmpty(parm.orderId) && !parm.orderId.StartsWith("0"), it => SqlFunc.Subqueryable<Transferorderitem>().Where(i => i.OrderId == it.OrderId && (i.Addon.Contains(parm.orderId) || i.SnCodes.Contains(parm.orderId))).Any())
                .Select((it, custer) => new Transferorder
                {
                    OrderId = it.OrderId,
                    UserId = it.UserId,
                    OldUserId = it.OldUserId,
                    NewUserld = it.NewUserld,
                    Type = it.Type,
                    Status = it.Status,
                    CreateTime = it.CreateTime,
                    UpdateTime = it.UpdateTime,
                    OrderAmt = it.OrderAmt,
                    //TransferorderitemNav = it.TransferorderitemNav,
                    NewUserName = custer.UserName
                })
                .Includes(x => x.TransferorderitemNav) //填充子对象
                .OrderByDescending(it => new { it.CreateTime })
                .ToPage<Transferorder, TransferorderDto>(parm);

            List<TransferorderitemDto> itemDetails = new List<TransferorderitemDto>();
            Dictionary<long, List<long>> _dictinfo = new Dictionary<long, List<long>>();
            foreach (var item in response.Result)
            {
                itemDetails.AddRange(item.TransferorderitemNav);
                if (_dictinfo.ContainsKey(item.UserId))
                {
                    _dictinfo[item.UserId].AddRange(item.TransferorderitemNav.Select(e => e.Id).ToList());
                }
                else
                {
                    _dictinfo.Add(item.UserId, item.TransferorderitemNav.Select(e => e.Id).ToList());
                }
            }
            var productIds = itemDetails.Select(item => item.ProductId).Distinct().ToList();
            var userIds = _dictinfo.Keys.Distinct().ToList();
            var goodIds = itemDetails.Select(item => item.GoodsId).Distinct().ToList();
            var stockList = Context.Queryable<Corecmsuserstock>()
                .Where(stock =>
                    productIds.Contains(stock.ProductId) &&
                    userIds.Contains(stock.UserId ?? 0) &&
                    goodIds.Contains(stock.GoodId)) // 新增 GoodId 过滤
                .ToList();
            foreach (var item in itemDetails)
            {
                var stockInfo = stockList.FirstOrDefault(stock =>
                    stock.ProductId == item.ProductId &&
                    stock.UserId == _dictinfo.Where(e => e.Value.Contains(item.Id)).First().Key &&
                    stock.GoodId == item.GoodsId); // 新增 GoodId 匹配

                if (stockInfo != null)
                {
                    item.Stock = stockInfo.Stock ?? 0;
                }
                else
                {
                    // 如果没有找到关联的库存信息，可根据业务需求设置默认值
                    item.Stock = 0;
                }
            }
            return response;
        }


        /// <summary>
        /// 获取详情
        /// </summary>
        /// <param name="OrderId"></param>
        /// <returns></returns>
        public Transferorder GetInfo(string OrderId)
        {
            var response = Queryable()
                .Includes(x => x.TransferorderitemNav) //填充子对象
                .Where(x => x.OrderId == OrderId)
                .First();

            return response;
        }

        /// <summary>
        /// 添加调仓单
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public WebApiCallBack AddTransferorder(Transferorder model)
        {
            var jm = new WebApiCallBack();
            model.OrderId = CommonHelper.GetSerialNumberType((int)SerialNumberType.调仓订单编号);
            model.Status = "2";
            model.OrderAmt = 0;

            var ids = model.TransferorderdetailNav.Select(d => d.ProductId);

            var goodIds = model.TransferorderitemNav.Select(d => d.GoodsId).Distinct();



            var res = UseTran(() =>
            {
                var prodList = Context.Queryable<Corecmsproducts>().Where(prod => ids.Contains(prod.Id)).ToList();
                var usList = Context.Queryable<Corecmsuserstock>().Where(prod => prod.UserId == model.UserId && ids.Contains(prod.ProductId)).ToList();


                var snCodes = model.TransferorderdetailNav.Select(d => d.SnCode);
                var codeList = Context.Queryable<Prodinfo>().Where(prod => snCodes.Contains(prod.SnCode)).ToList();

                if (codeList == null || codeList.Count <= 0)
                {
                    throw new CustomException("调仓失败, 不存在的商品");
                }

                codeList.ForEach(p =>
                {

                    if (model.Type == "1" && (!p.UserCusId.HasValue || p.UserCusId == 0))
                    {
                        throw new CustomException("调仓失败, " + p.SnCode + "非小仓商品，无需调回");
                    }
                    if (model.Type == "0" && p.UserCusId.HasValue && p.UserCusId > 0)
                    {
                        throw new CustomException("调仓失败, " + p.SnCode + "小仓商品无法调出，请先调回本仓");
                    }
                    if (model.Type == "1") //调回本仓
                    {
                        var cuUS = Context.Queryable<Corecmsuserstock>().Where(prod => prod.UserId == p.UserCusId && prod.ProductId == p.ProductId).First();
                        if (cuUS != null)
                        {
                            cuUS.Stock = (cuUS.Stock ?? 0) - 1;
                            if (cuUS.Stock < 0) cuUS.Stock = 0;
                            Context.Updateable<Corecmsuserstock>(cuUS).UpdateColumns(p => new { p.Stock }).ExecuteCommand();
                        }
                        p.UserCusId = 0;
                    }
                    else
                    {
                        var product = model.TransferorderitemNav.Where(item => item.ProductId == p.ProductId).First();
                        var cuUS = Context.Queryable<Corecmsuserstock>().Where(prod => prod.UserId == model.NewUserld && prod.ProductId == p.ProductId).First();
                        if (cuUS != null)
                        {
                            cuUS.Stock = (cuUS.Stock ?? 0) + 1;
                            if (cuUS.Stock <= 0) cuUS.Stock = 1;
                            Context.Updateable<Corecmsuserstock>(cuUS).UpdateColumns(p => new { p.Stock }).ExecuteCommand();
                        }
                        else
                        {
                            cuUS = new Corecmsuserstock
                            {
                                UserId = model.NewUserld,
                                GoodId = p.GoodsId,
                                ProductId = p.ProductId.Value,
                                Stock = 1,
                                CreateTime = DateTime.Now,
                                IsDel = false,
                                ProductCostPrice = 0,
                                Sn = product != null ? product.Sn : "",
                                BarCode = product != null ? product.BarCode : "",
                                SkuName = product != null ? product.Addon : "",
                                SkuImage = product != null ? product.ImageUrl : "",
                            };
                            Context.Insertable(cuUS).ExecuteCommand();
                        }
                        p.UserCusId = model.NewUserld;
                    }
                });

                model.TransferorderdetailNav.ForEach(p =>
                {
                    p.OrderId = model.OrderId;
                });

                model.TransferorderitemNav.ForEach(p =>
                {
                    model.OrderAmt += p.Amount;
                    p.OrderId = model.OrderId;
                    var pord = prodList.Where(prod => prod.Id == p.ProductId).FirstOrDefault();
                    if (pord != null)
                    {
                        p.Sn = pord.Sn;
                        p.BarCode = pord.Barcode;
                        p.GoodsId = pord.GoodsId;
                    }
                    p.CreateTime = model.CreateTime;

                    //更新库存
                    var us = usList.Where(u => u.ProductId == p.ProductId).FirstOrDefault();
                    if (us != null)
                    {
                        if (model.Type == "1") //调回本仓
                        {
                            ////调回本仓 需要增加本地库存
                            us.SaleStock = us.SaleStock + p.Nums;
                            us.Stock = us.Stock + p.Nums;
                            //减掉小仓库存
                            var miniStock = (us.MinStock.HasValue ? us.MinStock.Value : 0) - p.Nums;
                            us.MinStock = miniStock > 0 ? miniStock : 0;
                        }
                        else
                        {

                            ////调回本仓 需要增加本地库存
                            us.SaleStock = us.SaleStock - p.Nums;
                            us.Stock = us.Stock - p.Nums;
                            //减掉小仓库存
                            us.MinStock = (us.MinStock.HasValue ? us.MinStock.Value : 0) + p.Nums;
                        }
                    }
                });

                if (model.Type == "0")
                {
                    var ugs = Context.Queryable<Corecmsgoods>()
                                    .LeftJoin<Corecmsusergoods>((g, ug) => g.Id == ug.GoodId && ug.UserId == model.NewUserld)
                                    .Where((g, ug) => goodIds.Contains(g.Id)&&SqlFunc.IsNullOrEmpty(ug.Id))
                                    .Select((g, ug)=>new Corecmsusergoods { 
                                        GoodId=g.Id,
                                        GoodName=g.Name,
                                        GoodBrand=g.BrandId,
                                        SortId=1,
                                        UserId=model.NewUserld,
                                        GoodRefreshTime= DateTime.Now,
                                        CreateTime= DateTime.Now,
                                        Marketable=1,
                                        Images=g.Images
                                    }).ToList();
                    if (ugs != null && ugs.Count > 0) 
                    {
                        Context.Insertable<Corecmsusergoods>(ugs).ExecuteCommand();
                    }

                }

                var i = Context.Updateable<Corecmsuserstock>(usList).WhereColumns(p => new { p.Id }).UpdateColumns(p => new { p.SaleStock, p.Stock, p.MinStock }).ExecuteCommand();
                if (i <= 0) throw new CustomException("更新本仓库存，调仓失败");

                i = Context.Updateable<Prodinfo>(codeList).UpdateColumns(p => new { p.UserCusId }).WhereColumns(p => p.Id).ExecuteCommand();
                if (i <= 0) throw new CustomException("调仓失败");
                i = Context.Insertable<Transferorderdetail>(model.TransferorderdetailNav).ExecuteCommand();
                if (i <= 0) throw new CustomException("调仓失败");

                model = Context.InsertNav(model).Include(s1 => s1.TransferorderitemNav).ExecuteReturnEntity();

            });
            jm.status = res.IsSuccess;
            jm.msg = res.ErrorMessage;
            jm.data = model;
            return jm;
            //return res.IsSuccess ? model : throw new CustomException("调仓失败");


        }

        /// <summary>
        /// 修改调仓单
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public int UpdateTransferorder(Transferorder model)
        {
            return Context.UpdateNav(model).Include(z1 => z1.TransferorderitemNav).ExecuteCommand() ? 1 : 0;
        }

        /// <summary>
        /// 查询导出表达式
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        private static Expressionable<Transferorder> QueryExp(TransferorderQueryDto parm)
        {
            var predicate = Expressionable.Create<Transferorder>();
            predicate = predicate.AndIF(parm.UserId.HasValue, it => it.UserId == parm.UserId);
            //predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.orderId), it => it.OrderId == parm.orderId);
            predicate = predicate.AndIF(parm.BeginCreateTime == null, it => it.CreateTime >= DateTime.Now.AddDays(-365).ToShortDateString().ParseToDateTime());
            predicate = predicate.AndIF(parm.BeginCreateTime != null, it => it.CreateTime >= parm.BeginCreateTime);
            predicate = predicate.AndIF(parm.EndCreateTime != null, it => it.CreateTime <= parm.EndCreateTime);
            return predicate;
        }

        public WebApiCallBack ItemsPacking(Transferorder model)
        {
            var jm = new WebApiCallBack();
            var result = UseTran(() =>
            {
                // 补充 orderId 到 TransferorderdetailNav
                foreach (var detail in model.TransferorderdetailNav)
                {
                    detail.OrderId = model.OrderId;
                }
                var snCodes = model.TransferorderdetailNav.Select(d => d.SnCode);
                var codeList = Context.Queryable<Prodinfo>().Where(prod => prod.UserId == model.OldUserId && snCodes.Contains(prod.SnCode)).ToList();

                if (codeList == null || codeList.Count <= 0)
                {
                    throw new CustomException("调仓失败, 不存在的商品");
                }

                codeList.ForEach(p =>
                {
                    if (p.UserCusId.HasValue && p.UserCusId > 0)
                    {
                        throw new CustomException("调仓失败, " + p.SnCode + "小仓商品无法调出，请先调回本仓");
                    }

                    p.UserCusId = model.NewUserld;
                });

                var insertDetailResult = Context.Insertable<Transferorderdetail>(model.TransferorderdetailNav).ExecuteCommand();
                if (insertDetailResult <= 0)
                {
                    throw new CustomException("插入调仓单详情数据失败");
                }
                insertDetailResult = Context.Updateable<Prodinfo>(codeList).UpdateColumns(p => new { p.UserCusId }).WhereColumns(p => p.Id).ExecuteCommand();
                if (insertDetailResult <= 0) throw new CustomException("调仓失败");

                // 去掉 TransferorderitemNav 中 SnCodes 的左右空格
                foreach (var item in model.TransferorderitemNav)
                {
                    if (!string.IsNullOrEmpty(item.SnCodes))
                    {
                        item.SnCodes = item.SnCodes.Trim();
                    }
                }

                // 根据 orderId, goodId, productId 匹配更新到表 transferorderitem
                var updateItemResult = Context.Updateable<Transferorderitem>(model.TransferorderitemNav)
                    .WhereColumns(it => new { it.OrderId, it.GoodsId, it.ProductId })
                    .UpdateColumns(it => new { it.SnCodes }) // 仅更新 SnCodes 字段
                    .ExecuteCommand();
                if (updateItemResult <= 0)
                {

                    throw new CustomException("更新调仓单项数据失败");
                }

                // 根据 goodId, productId 以及扫描数据更新库存加减
                foreach (var item in model.TransferorderitemNav)
                {
                    // 根据 oldUserId 匹配商品进行减库存
                    var oldUserStock = Context.Queryable<Corecmsuserstock>()
                        .Where(stock => stock.UserId == model.OldUserId &&
                                        stock.GoodId == item.GoodsId &&
                                        stock.ProductId == item.ProductId)
                        .First();

                    if (oldUserStock != null)
                    {
                        oldUserStock.Stock -= item.scannedNum;
                        oldUserStock.SaleStock -= item.scannedNum;
                        oldUserStock.MinStock = (oldUserStock.MinStock.HasValue ? oldUserStock.MinStock.Value : 0) + item.scannedNum;
                        var oldUpdateResult = Context.Updateable(oldUserStock)
                            .UpdateColumns(stock => new { stock.Stock, stock.MinStock, stock.SaleStock })
                            .ExecuteCommand();
                        if (oldUpdateResult <= 0)
                        {

                            throw new CustomException("更新原用户库存失败");
                        }
                    }

                    // 根据 newUserId 进行加库存
                    var newUserStock = Context.Queryable<Corecmsuserstock>()
                        .Where(stock => stock.UserId == model.NewUserld &&
                                        stock.GoodId == item.GoodsId &&
                                        stock.ProductId == item.ProductId)
                        .First();

                    if (newUserStock != null)
                    {
                        newUserStock.Stock = (newUserStock.Stock.HasValue ? newUserStock.Stock.Value : 0) + item.scannedNum;
                        var newUpdateResult = Context.Updateable(newUserStock)
                            .UpdateColumns(stock => new { stock.Stock })
                            .ExecuteCommand();
                        if (newUpdateResult <= 0)
                        {
                            throw new CustomException("更新新用户库存失败");
                        }
                    }
                    else
                    {
                        // 如果新用户库存记录不存在，则创建新记录
                        newUserStock = new Corecmsuserstock
                        {
                            UserId = model.NewUserld,
                            GoodId = item.GoodsId,
                            ProductId = item.ProductId,
                            Stock = item.scannedNum,
                            ProductCostPrice = item.Price,
                            Marketable = 1,
                            SkuImage = item.ImageUrl,
                            Sn = item.Sn,
                            BarCode = item.BarCode,
                            SkuName = item.Addon
                        };
                        logger.Error($"新增库存记录{JsonConvert.SerializeObject(newUserStock)}");
                        var insertNewStockResult = Context.Insertable(newUserStock).ExecuteCommand();
                        if (insertNewStockResult <= 0)
                        {

                            throw new CustomException("创建新用户库存记录失败");
                        }
                    }
                }

                // 根据扫描数量和铺货数量判断更新 model 的 status 字段
                bool allCompleted = true;


                model.Status = allCompleted ? "2" : "1";

                // 更新 model 的状态到数据库
                var updateStatusResult = Context.Updateable(model)
                    .UpdateColumns(it => new { it.Status, it.UpdateTime, it.OrderAmt })
                    .ExecuteCommand();
                if (updateStatusResult <= 0)
                {
                    throw new CustomException("更新调仓单状态失败");
                }

            });

            jm.status = result.IsSuccess ? true : false;
            jm.msg = result.IsSuccess ? "调仓单更新成功" : result.ErrorMessage;
            jm.data = model;
            return jm;
        }

        public WebApiCallBack CancelOrder(string orderId)
        {
            var jm = new WebApiCallBack();
            try
            {
                // 查询要取消的订单
                var order = Context.Queryable<Transferorder>()
                    .Where(it => it.OrderId == orderId)
                    .First();

                if (order == null)
                {
                    jm.status = false;
                    jm.msg = "未找到指定的调仓订单";
                    return jm;
                }

                // 修改订单状态为 3
                order.Status = "3";
                order.UpdateTime = DateTime.Now;
                // 更新数据库中的订单状态
                var updateResult = Context.Updateable(order)
                    .UpdateColumns(it => new { it.Status, it.UpdateTime })
                    .ExecuteCommand();

                if (updateResult <= 0)
                {
                    jm.status = false;
                    jm.msg = "订单取消失败";
                }
                else
                {
                    jm.status = true;
                    jm.msg = "订单取消成功";
                }
            }
            catch (Exception ex)
            {
                jm.status = false;
                jm.msg = "取消订单时出现异常: " + ex.Message;
            }
            return jm;
        }

        //补货
        public WebApiCallBack AddTransferorder2(Transferorder model)
        {
            var jm = new WebApiCallBack();
            model.OrderId = CommonHelper.GetSerialNumberType((int)SerialNumberType.调仓订单编号);
            model.Status = "4";
            model.OrderAmt = 0;

            var ids = model.TransferorderdetailNav.Select(d => d.ProductId);


            var res = UseTran(() =>
            {
                var prodList = Context.Queryable<Corecmsproducts>().Where(prod => ids.Contains(prod.Id)).ToList();
                var usList = Context.Queryable<Corecmsuserstock>().Where(prod => prod.UserId == model.UserId && ids.Contains(prod.ProductId)).ToList();

                var snCodes = model.TransferorderdetailNav.Select(d => d.SnCode);
                //var codeList = Context.Queryable<Prodinfo>().Where(prod => snCodes.Contains(prod.SnCode)).ToList();

                //if (codeList == null || codeList.Count <= 0)
                //{
                //    throw new CustomException("调仓失败, 不存在的商品");
                //}

                //codeList.ForEach(p =>
                //{

                //    if (model.Type == "1" && (!p.UserCusId.HasValue || p.UserCusId == 0))
                //    {
                //        throw new CustomException("调仓失败, " + p.SnCode + "非小仓商品，无需调回");
                //    }
                //    if (model.Type == "0" && p.UserCusId.HasValue && p.UserCusId > 0)
                //    {
                //        throw new CustomException("调仓失败, " + p.SnCode + "小仓商品无法调出，请先调回本仓");
                //    }
                //    if (model.Type == "1") //调回本仓
                //    {
                //        p.UserCusId = 0;
                //    }
                //    else
                //    {
                //        p.UserCusId = model.NewUserld;
                //    }
                //});

                model.TransferorderdetailNav.ForEach(p =>
                {
                    p.OrderId = model.OrderId;
                });

                model.TransferorderitemNav.ForEach(p =>
                {
                    model.OrderAmt += p.Amount;
                    p.OrderId = model.OrderId;
                    var pord = prodList.Where(prod => prod.Id == p.ProductId).FirstOrDefault();
                    if (pord != null)
                    {
                        p.Sn = pord.Sn;
                        p.BarCode = pord.Barcode;
                        p.GoodsId = pord.GoodsId;
                    }
                    p.CreateTime = model.CreateTime;

                    //更新库存
                    //var us = usList.Where(u => u.ProductId == p.ProductId).FirstOrDefault();
                    //if (us != null)
                    //{
                    //    if (model.Type == "1") //调回本仓
                    //    {
                    //        ////调回本仓 需要增加本地库存
                    //        us.SaleStock = us.SaleStock + p.Nums;
                    //        us.Stock = us.Stock + p.Nums;
                    //        //减掉小仓库存
                    //        us.MinStock = us.MinStock - p.Nums;
                    //    }
                    //    else
                    //    {

                    //        ////调回本仓 需要增加本地库存
                    //        us.SaleStock = us.SaleStock - p.Nums;
                    //        us.Stock = us.Stock - p.Nums;
                    //        //减掉小仓库存
                    //        us.MinStock = us.MinStock + p.Nums;
                    //    }
                    //}
                });

                //var i = Context.Updateable<Corecmsuserstock>(usList).WhereColumns(p => new { p.Id }).UpdateColumns(p => new { p.SaleStock, p.Stock, p.MinStock }).ExecuteCommand();
                //if (i <= 0) throw new CustomException("更新本仓库存，调仓失败");

                //i = Context.Updateable<Prodinfo>(codeList).UpdateColumns(p => new { p.UserCusId }).WhereColumns(p => p.Id).ExecuteCommand();
                //if (i <= 0) throw new CustomException("调仓失败");
                var i = Context.Insertable<Transferorderdetail>(model.TransferorderdetailNav).ExecuteCommand();
                if (i <= 0) throw new CustomException("调仓失败");

                model = Context.InsertNav(model).Include(s1 => s1.TransferorderitemNav).ExecuteReturnEntity();

            });
            jm.status = res.IsSuccess;
            jm.msg = res.ErrorMessage;
            jm.data = model;
            return jm;
            //return res.IsSuccess ? model : throw new CustomException("调仓失败");


        }
    }
}